/**
 * =====================================================================================
 *       @file  ngx_event.h
 *      @brief  
 *
 *  Detailed description starts here.
 *
 *   @internal
 *     Created  2012年05月09日 22时28分07秒 
 *    Revision  1.0.0.0
 *    Compiler  gcc/g++
 *
 *     @author  luis
 * =====================================================================================
 */

#ifndef H_NGX_EVENT_H_INCLUDED_
#define H_NGX_EVENT_H_INCLUDED_

#include <sys/epoll.h>
#include "ngx_core.h"
#include "ngx_config.h"
#include "ngx_string.h"
#include "ngx_shmtx.h"
#include "ngx_os.h"

#define NGX_INVALID_INDEX 0xd0d0d0d0

struct ngx_event_s
{
    void                       *data;

    ngx_event_handler_pt        handler;

    unsigned                    active:1;
    unsigned                    closed:1;
    unsigned                    write:1;
    unsigned                    instance:1;
    unsigned                    accept:1;
    unsigned                    ready:1;
    unsigned                    available:1;
    unsigned                    eof:1;
    unsigned                    error:1;

    ngx_uint_t                  index;

    ngx_event_t                *next;
    ngx_event_t               **prev;
};

typedef struct
{
    ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
    ngx_int_t (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);

    ngx_int_t (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
    ngx_int_t (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);

    ngx_int_t (*add_conn)(ngx_connection_t *c);
    ngx_int_t (*del_conn)(ngx_connection_t *c);

    ngx_int_t (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t nowait);
    ngx_int_t (*process_events)(ngx_cycle_t *cycle, ngx_uint_t timer, ngx_uint_t flags);

    ngx_int_t (*init)(ngx_cycle_t *cycle);
    void       (*done)(ngx_cycle_t *cycle);

} ngx_event_actions_t;

typedef struct
{
    ngx_str_t           *name;

    void              *(*create_conf)(ngx_cycle_t *cycle);
    char              *(*init_conf)(ngx_cycle_t *cycle, void *conf);

    ngx_event_actions_t  actions;
} ngx_event_module_t;

extern ngx_uint_t              ngx_event_flags;
extern ngx_event_actions_t      ngx_event_actions;

void ngx_process_events_and_timers(ngx_cycle_t *cycle);

extern ngx_atomic_t    *ngx_accept_mutex_ptr;
extern ngx_uint_t       ngx_use_accept_mutex;
extern ngx_int_t        ngx_accept_disabled;
extern ngx_int_t        ngx_accept_mutex_held;
extern ngx_int_t        ngx_accept_events;
extern ngx_shmtx_t      ngx_accept_mutex;

extern ngx_module_t     ngx_events_module;
extern ngx_module_t     ngx_event_core_module;

ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle);

#define NGX_EVENT_MODULE        0X544e5645
#define NGX_USE_GREEDY_EVENT    0x00000020

#define NGX_READ_EVENT          EPOLLIN
#define NGX_WRITE_EVENT         EPOLLOUT

#define ngx_add_event           ngx_event_actions.add
#define ngx_del_event           ngx_event_actions.del
#define ngx_process_events      ngx_event_actions.process_events

#define NGX_CLOSE_EVENT         1

#define NGX_POST_EVENTS         1

void ngx_event_accept(ngx_event_t *ev);

extern ngx_os_io_t ngx_io;

#define ngx_recv        ngx_io.recv
#define ngx_recv_chain  ngx_io.recv_chain
#define ngx_udp_recv    ngx_io.udp_recv
#define ngx_send        ngx_io.send
#define ngx_send_chain  ngx_io.send_chain

#define NGX_CLEAR_EVENT EPOLLET



#endif
